#include "ir_send.h"
#include "stdio.h"
#define  QUEUE_SIZE        4
#define  DATA_BITS         8
#define  IR_SEND_TIME_1MS 100
#define  IR_SEND_TIME_3MS 300

uint8_t ir_send_pwm = 0;

uint8_t send_queue[QUEUE_SIZE] = {0};
uint8_t send_queue_head = 0;
uint8_t send_queue_tail = 0;
uint8_t send_queue_count = 0;

SendState send_state = SEND_IDLE;
uint8_t send_bit_count = 0;
uint16_t send_timer_start = 0;
uint16_t high_send_timer = 0;
uint16_t low_send_timer = 0;
uint8_t current_send_data = 0;
volatile uint16_t custom_tick = 0;

uint16_t get_elapsed_time(uint16_t previous_time) 
{
    uint16_t current_time = custom_tick;
    return (current_time >= previous_time) ? (current_time - previous_time) : (0xFFFF - previous_time + current_time + 1);
}
uint8_t enqueue_send_data(uint8_t recv_data)
{
	uint8_t send_data = 0;
    if (send_queue_count >= QUEUE_SIZE) 
		return 0;
    switch(recv_data)
    {
		case KEY1:
			send_data = 0xA1;
            break;
		case KEY2:
			send_data = 0xAB;
            break;
		case KEY3:
			send_data = 0xAD;
            break;
		case KEY4:
			send_data = 0xAE;
            break;
		default:
			send_data = 0x00;
            break;
    }
    send_queue[send_queue_tail] = send_data;
    send_queue_tail = (send_queue_tail + 1) % QUEUE_SIZE;
    send_queue_count++;
    printf("send queue data:%x_%x_%x_%x\r\n",send_queue[0],send_queue[1],send_queue[2],send_queue[3]);
    return 1;
}


uint8_t dequeue_send_data(uint8_t *data) {
    if (send_queue_count == 0) 
		return 0;
    *data = send_queue[send_queue_head];
    send_queue_head = (send_queue_head + 1) % QUEUE_SIZE;
    send_queue_count--;
    return 1;
}

void send_state_machine(void) {
    switch (send_state) 
    {
        case SEND_IDLE:
            if (dequeue_send_data(&current_send_data))
            {
                send_bit_count = 0;
                send_state = SEND_HIGH;
            }
            break;

        case SEND_HIGH:
			
            if (current_send_data & (1 << (7 - send_bit_count)))
            {
                ir_send_pwm = 1;
                HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_SET);
                high_send_timer = IR_SEND_TIME_3MS;
                low_send_timer = IR_SEND_TIME_1MS;
            } 
            else 
            {
                ir_send_pwm = 1;
                HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_SET);
                high_send_timer = IR_SEND_TIME_1MS;
                low_send_timer = IR_SEND_TIME_3MS;
            }
            send_timer_start = custom_tick;
            send_state = SEND_LOW;
            break;

        case SEND_LOW:
            if (get_elapsed_time(send_timer_start) >= high_send_timer)
            {
                ir_send_pwm = 0;
                HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_RESET);
                send_timer_start = custom_tick;
                send_state = SEND_COMPLETE;
            }
            break;

        case SEND_COMPLETE:
            if (get_elapsed_time(send_timer_start) >= low_send_timer) 
            {
                send_bit_count++;
                if (send_bit_count == DATA_BITS) 
                {
                    send_state = SEND_IDLE;
                }
                else 
                {
                    send_state = SEND_HIGH;
                }
            }
            break;
    }
}